package com.greenyoung.pwiki.elasticsearch.index.utils;

import com.greenyoung.pwiki.common.consts.ConstElPipeline;
import org.elasticsearch.action.ingest.GetPipelineRequest;
import org.elasticsearch.action.ingest.GetPipelineResponse;
import org.elasticsearch.action.ingest.PutPipelineRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.ingest.PipelineConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * 为了使spring能够注入RestHighLevelClient,需将其加上@Component注解，表示这是spring的一部分
 */
@Component
public class PipelineUtils {

    private static RestHighLevelClient client;
    private static Logger logger = LoggerFactory.getLogger(PipelineUtils.class);

    /**
     * Let Spring inject the provided RestHighLevelClient bean in the constructor.
     * 不要直接使用@Autowired
     *
     * @param client 来自ElasticsearchConfig中
     * @see com.greenyoung.pwiki.elasticsearch.index.config.ElasticsearchConfig
     */
    public PipelineUtils(@Qualifier("elasticsearchClient") RestHighLevelClient client) {
        PipelineUtils.client = client;
    }

    /**
     * 利用el自带的api创建pipeline
     * see https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-ingest-put-pipeline.html
     *
     * @return 是否创建成功/是否存在
     * @throws Exception
     */
    public static boolean checkAndCreatePipeline() throws IOException {
        if (isPipelineExists()) {
            return true;
        }

        PutPipelineRequest request = new PutPipelineRequest(
                ConstElPipeline.PIPELINE_ID,
                new BytesArray(ConstElPipeline.PIPELINE_CONFIG.getBytes(StandardCharsets.UTF_8)),
                XContentType.JSON
        );

        AcknowledgedResponse response = client.ingest().putPipeline(request, RequestOptions.DEFAULT);
        boolean acknowledged = response.isAcknowledged();

        if (acknowledged) {
            logger.info("[+] pipeline: " + ConstElPipeline.PIPELINE_ID + " 创建完成\tconfig:" + ConstElPipeline.PIPELINE_CONFIG);
        } else {
            logger.error("[!] pipeline: " + ConstElPipeline.PIPELINE_ID + " 创建失败\tconfig:" + ConstElPipeline.PIPELINE_CONFIG);
        }
        return acknowledged;
    }

    /**
     * 使用elasticsearch自带的api检查pipeline是否已创建
     * see https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-ingest-get-pipeline.html
     *
     * @return 是否已有pipeline存在
     */
    private static boolean isPipelineExists() throws IOException {
        GetPipelineRequest request = new GetPipelineRequest(ConstElPipeline.PIPELINE_ID);
        GetPipelineResponse response = PipelineUtils.client.ingest().getPipeline(request, RequestOptions.DEFAULT);
        boolean successful = response.isFound();
        if (!successful) {
            logger.info("[-] pipeline: " + ConstElPipeline.PIPELINE_ID + " 未创建");
        }
        List<PipelineConfiguration> pipelines = response.pipelines();
        for (PipelineConfiguration pipeline : pipelines) {
            Map<String, Object> config = pipeline.getConfigAsMap();
            logger.info("[*] pipeline: " + ConstElPipeline.PIPELINE_ID + " 已存在\tconfig:" + config);
        }
        return successful;
    }


}
